#include<iostream>
#include<vector>
using namespace std;
class Solution {
private:
    static constexpr int directions[4][2] = { {0, 1}, {1, 0}, {0, -1}, {-1, 0} };
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) 
    {
        if (matrix.size() == 0 || matrix[0].size() == 0) 
            return {};
        int rows = matrix.size(), columns = matrix[0].size();
        vector<vector<bool>> visited(rows, vector<bool>(columns));
        int total = rows * columns;
        vector<int> order(total);

        int row = 0, column = 0;
        int directionIndex = 0;
        for (int i = 0; i < total; i++) 
        {
            order[i] = matrix[row][column];
            visited[row][column] = true;
            int nextRow = row + directions[directionIndex][0], nextColumn = column + directions[directionIndex][1];
            if (nextRow < 0 || nextRow >= rows || nextColumn < 0 || nextColumn >= columns || visited[nextRow][nextColumn]) 
            {
                directionIndex = (directionIndex + 1) % 4;
            }
            row += directions[directionIndex][0];
            column += directions[directionIndex][1];
        }
        return order;
    }
};
int main()
{
    vector<vector<int>> matrix{ {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
    vector<int> retnums;
    retnums.reserve(matrix.size() * matrix[0].size());
    retnums = Solution().spiralOrder(matrix);
    for (const auto& num : retnums)
        cout << num << " ";
    cout << endl;
    return 0;
}